﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using eLearning.Models;
using eLearning.Business;
using eLearning.Helpers;
using eLearning.ViewModels;
using System.Web.Mvc;

namespace eLearning.Repository
{
    public class FieldManagementRepository
    {
        // Create an instance of entities framework
        Lead2012Entities entities = new Lead2012Entities();

        public void GetModel(FieldViewModel model)
        {
            // Set value
            model.ListFields = GetFieldGroup();
            model.FieldType = GetAllFielType();
            model.LeadType = GetAllLeadFormType();
            model.VisibilityType = GetAllVisibilityType();
            model.GroupFieldType = GetAllGroupFields();
        }

        public void GetModelSettings(FieldViewModel model)
        {
            // Set value
            model.ListFields = GetFieldGroup();
            model.FieldSystemList = new FieldSystemRepository().GetAll();
            //model.FieldType = GetAllFielType();
            //model.GroupFieldType = GetAllGroupFields();
        }


        public FieldTypeGroupInfo GetFieldTypeGroupInfo(int id)
        {
            FieldTypeGroupInfo model = new FieldTypeGroupInfo();

            var items = (from ft in entities.FieldTypes
                         join f in entities.Fields on ft.TypeId equals f.FieldType.TypeId
                         join fc in entities.FieldCustoms on f.FieldId equals fc.FieldId
                         join fg in entities.FieldGroups on fc.GroupId equals fg.GroupId
                         where f.FieldId == id
                         select new
                         {
                             Filterable = fc.Filterable,
                             Id = fc.FieldId,
                             LenderSafe = fc.LenderSafe,
                             OrderId = fc.OrderId,
                             GroupId = fg.ParentId,
                             SectionId = fg.GroupId,
                             Printable = fc.Printable,
                             Required = fc.Required,
                             Tag = f.Description,
                             TextColumnName = f.Title,
                             Title = f.Title,
                             ToolTip = fc.ToolTip,
                             TypeId = ft.TypeId,
                             TypeName = ft.Title,
                             ValueColumnName = ft.Title,
                             VisibilityId = fc.VisibilityId
                         }).FirstOrDefault();

            // set model
            if (items != null)
            {
                model.FieldTypeId = items.TypeId;
                model.Filterable = items.Filterable;
                model.Id = id;
                model.OrderId = items.OrderId;
                model.Printable = items.Printable;
                model.Required = items.Required;
                model.Title = items.Title;
                model.Tooltip = items.ToolTip;
                model.VisibilityId = items.VisibilityId;

                // Set section/group
                if (items.GroupId != null && items.GroupId.Value > 0)
                {
                    model.GroupId = items.GroupId.Value;
                    model.SectionId = items.SectionId;
                }
                else
                {
                    model.GroupId = items.SectionId;
                    model.SectionId = 0;
                }

                // Get lead form type
                FieldCustomLeadFormTypeRepository fcRepository = new FieldCustomLeadFormTypeRepository();
                model.LeadTypeId = fcRepository.GetSingle(id);
            }

            return model;
        }

        #region #Build Form Builder
        private List<ItemFilter> GetAllLeadFormType()
        {
            List<ItemFilter> list = new List<ItemFilter>();

            var items = (from c in entities.LeadFormTypes
                         select c).ToList();

            // Add item to list
            list.Add(new ItemFilter { ID = "0", ItemName = "All" });
            foreach (var item in items)
            {
                ItemFilter model = new ItemFilter();
                model.ID = item.TypeId.ToString();
                model.ItemName = item.Title;
                list.Add(model);
            }
            
            return list;
        }

        private List<LeadFormTypeInfo> GetLeadFormTypeByFieldId(int fieldId)
        {
            List<LeadFormTypeInfo> list = new List<LeadFormTypeInfo>();

            var items = (from c in entities.LeadFormTypes
                         join fl in entities.FieldCustomLeadFormTypes on c.TypeId equals fl.TypeId
                         where fl.FieldId == fieldId
                         select c).ToList();

            // Add item to list
            foreach (var item in items)
            {
                LeadFormTypeInfo model = new LeadFormTypeInfo();
                model.Id = item.TypeId;
                model.Name = item.Title;
                list.Add(model);
            }
            
            return list;
        }

        private List<GroupItemFilter> GetAllGroupFields()
        {
            List<GroupItemFilter> list = new List<GroupItemFilter>();

            var items = (from c in entities.FieldGroups
                         orderby c.OrderId ascending
                         select c);

            foreach (var item in items)
            {
                GroupItemFilter model = new GroupItemFilter();
                model.ID = item.GroupId.ToString();
                model.ParentId = (item.ParentId != null) ? item.ParentId.Value : 0;
                model.ItemName = item.Title;
                list.Add(model);
            }

            return list;
        }

        public List<FieldGroupInfo> GetFieldGroup()
        {
            List<FieldGroupInfo> list = new List<FieldGroupInfo>();

            // Get all groups
            var groupList = GetAllGroups();
            var fieldTypeList = GetAllFieldTypes();
            var fieldInfoList = GetAllFieldInfo();

            // Loop add fieldGroup
            foreach (var item in groupList.Where(c => c.ParentId == null || c.ParentId.Value == 0).OrderBy(c => c.OrderId))
            {
                FieldGroupInfo group = new FieldGroupInfo();

                group.Id = item.GroupId;
                group.Title = item.Title;
                group.OrderId = item.OrderId;
                group.ParentId = (item.ParentId != null) ? item.ParentId.Value : 0;

                // Get all fields of group
                group.Fields = GetAllFieldByGroupId(item.GroupId, fieldInfoList);

                // Get all section/fields of group
                group.Groups = GetAllGroup(item.GroupId, groupList, fieldInfoList);

                list.Add(group);
            }

            return list;
        }

        public List<FieldGroupInfo> GetFieldGroupForPrint()
        {
            List<FieldGroupInfo> list = new List<FieldGroupInfo>();

            // Get all groups
            var groupList = GetAllGroups();
            var fieldTypeList = GetAllFieldTypes();
            var fieldInfoList = GetAllFieldInfoForPrint();

            // Loop add fieldGroup
            foreach (var item in groupList.Where(c => c.ParentId == null || c.ParentId.Value == 0).OrderBy(c => c.OrderId))
            {
                FieldGroupInfo group = new FieldGroupInfo();

                group.Id = item.GroupId;
                group.Title = item.Title;
                group.OrderId = item.OrderId;
                group.ParentId = (item.ParentId != null) ? item.ParentId.Value : 0;

                // Get all fields of group
                group.Fields = GetAllFieldByGroupId(item.GroupId, fieldInfoList);

                // Get all section/fields of group
                group.Groups = GetAllGroup(item.GroupId, groupList, fieldInfoList);

                list.Add(group);
            }

            return list;
        }

        private List<ItemFilter> GetAllFielType()
        {
            List<ItemFilter> list = new List<ItemFilter>();

            var items = (from c in entities.FieldTypes
                         where c.TypeId != 32768
                         orderby c.OrderId ascending
                         select c);

            // Loop on each items
            foreach (var item in items)
            {
                ItemFilter model = new ItemFilter();
                model.ID = item.TypeId.ToString();
                model.ItemName = item.Title;
                list.Add(model);
            }

            return list;
        } 
        private List<ItemFilter> GetAllVisibilityType()
        {
            List<ItemFilter> list = new List<ItemFilter>();

            list.Add(new ItemFilter { ID = "-1", ItemName = "Read Only" });
            list.Add(new ItemFilter { ID = "0", ItemName = "No" });
            list.Add(new ItemFilter { ID = "1", ItemName = "Yes" });

            return list;
        } 
        #endregion

        #region #Common     
        private List<FieldGroupInfo> GetAllGroup(int groupId, List<FieldGroup> listGroup, List<FieldInfo> listField)
        {
            List<FieldGroupInfo> list = new List<FieldGroupInfo>();

            foreach (var item in listGroup.Where(c => c.ParentId == groupId).OrderBy(c => c.OrderId))
            {
                FieldGroupInfo model = new FieldGroupInfo();

                model.Id = item.GroupId;
                model.Title = item.Title;
                model.ParentId = groupId;

                // Add fields to section here
                model.Fields = GetAllFieldByGroupId(item.GroupId, listField);

                list.Add(model);
            }


            return list;
        }

        private List<FieldInfo> GetAllFieldByGroupId(int groupId, List<FieldInfo> list)
        {
            return list.Where(c => c.GroupId == groupId).OrderBy(c => c.OrderId).ToList();
        }

        private List<FieldGroup> GetAllGroups()
        {
            return (from c in entities.FieldGroups select c).ToList();
        }
        private List<FieldType> GetAllFieldTypes()
        {
            return (from c in entities.FieldTypes select c).ToList();
        }
        public List<FieldInfo> GetAllFieldInfo()
        {
            List<FieldInfo> list = new List<FieldInfo>();

            var items= (from ft in entities.FieldTypes
                    join f in entities.Fields on ft.TypeId equals f.FieldType.TypeId
                    join fc in entities.FieldCustoms on f.FieldId equals fc.FieldId
                    select new
                    {
                        Filterable = fc.Filterable,
                        GroupId = fc.GroupId,
                        Id = fc.FieldId,
                        LenderSafe = fc.LenderSafe,
                        OrderId = fc.OrderId,
                        Printable = fc.Printable,
                        Required = fc.Required,
                        Tag = f.Description,
                        TextColumnName = f.Title,
                        Title = f.Title,
                        ToolTip = fc.ToolTip,
                        TypeId = ft.TypeId,
                        TypeName = ft.Title,
                        ValueColumnName = ft.Title,
                        Visibility = fc.VisibilityId
                    });

            // Loop on items
            foreach (var item in items)
            {
                FieldInfo model = new FieldInfo();

                model.Filterable = item.Filterable;
                model.GroupId = item.GroupId;
                model.Id = item.Id;
                model.LenderSafe = item.LenderSafe;
                model.OrderId = item.OrderId;
                model.Printable = item.Printable;
                model.Required = item.Required;
                model.Tag = item.Tag;
                model.TextColumnName = item.TextColumnName;
                model.Title = item.Title;
                model.ToolTip = item.ToolTip;
                model.TypeId = item.TypeId;
                model.TypeName = item.TypeName;
                model.ValueColumnName = item.ValueColumnName;

                if (item.Visibility == -1)
                    model.Visibility = "READONLY";
                else if (item.Visibility == 0)
                    model.Visibility = "INVISIBLE";
                else
                    model.Visibility = "VISIBLE";

                // Add LeadFormTypes
                model.LeadFormTypes = GetLeadFormTypeByFieldId(item.Id);

                // Add data sources
                model.DataSource = GetAllFieldItemsByField(model, new FieldItemManagementRepository().GetAllItemByField(model.Id));

                list.Add(model);
            }

            return list;
        }
        
        public List<FieldInfo> GetAllFieldInfoForPrint()
        {
            List<FieldInfo> list = new List<FieldInfo>();

            var items= (from ft in entities.FieldTypes
                    join f in entities.Fields on ft.TypeId equals f.FieldType.TypeId
                    join fc in entities.FieldCustoms on f.FieldId equals fc.FieldId
                    where fc.Printable == true
                    select new
                    {
                        Filterable = fc.Filterable,
                        GroupId = fc.GroupId,
                        Id = fc.FieldId,
                        LenderSafe = fc.LenderSafe,
                        OrderId = fc.OrderId,
                        Printable = fc.Printable,
                        Required = fc.Required,
                        Tag = f.Description,
                        TextColumnName = f.Title,
                        Title = f.Title,
                        ToolTip = fc.ToolTip,
                        TypeId = ft.TypeId,
                        TypeName = ft.Title,
                        ValueColumnName = ft.Title,
                        Visibility = fc.VisibilityId
                    });

            // Loop on items
            foreach (var item in items)
            {
                FieldInfo model = new FieldInfo();

                model.Filterable = item.Filterable;
                model.GroupId = item.GroupId;
                model.Id = item.Id;
                model.LenderSafe = item.LenderSafe;
                model.OrderId = item.OrderId;
                model.Printable = item.Printable;
                model.Required = item.Required;
                model.Tag = item.Tag;
                model.TextColumnName = item.TextColumnName;
                model.Title = item.Title;
                model.ToolTip = item.ToolTip;
                model.TypeId = item.TypeId;
                model.TypeName = item.TypeName;
                model.ValueColumnName = item.ValueColumnName;

                if (item.Visibility == -1)
                    model.Visibility = "READONLY";
                else if (item.Visibility == 0)
                    model.Visibility = "INVISIBLE";
                else
                    model.Visibility = "VISIBLE";

                // Add LeadFormTypes
                model.LeadFormTypes = GetLeadFormTypeByFieldId(item.Id);

                // Add data sources
                model.DataSource = GetAllFieldItemsByField(model, new FieldItemManagementRepository().GetAllItemByField(model.Id));

                list.Add(model);
            }

            return list;
        }

        // Get Items by Field Id
        public List<SelectListItem> GetAllFieldItemsByField(FieldInfo model, List<FieldItemInfo> listFieldItems)
        {
            List<SelectListItem> list = new List<SelectListItem>();

            if (model.TypeId == 64 || model.TypeId == 1024 && listFieldItems != null)
            {
                foreach (var item in listFieldItems)
                {
                    SelectListItem option = new SelectListItem();
                    option.Value = item.Id.ToString();
                    option.Text = item.Title;
                    option.Selected = (model.Value == item.Id.ToString()) ? true : false;
                    list.Add(option);
                }

                if (model.TypeId == 64)
                {
                    list.Insert(0, new SelectListItem() { Selected = false, Text = string.Format("Chọn {0}", model.Title), Value = "" });
                }
            }
            else if (model.TypeId == 32)
            {
                // State
                var listStates = new StateRepository().GetAll();
                foreach (var item in listStates)
                {
                    SelectListItem option = new SelectListItem();
                    option.Value = item.StateId.ToString();
                    option.Text = item.Title;
                    option.Selected = (model.Value == item.StateId) ? true : false;
                    list.Add(option);
                }
                list.Insert(0, new SelectListItem() { Selected = false, Text = "Chọn tỉnh/thành", Value = "" });
            }

            return list;
        }

        #endregion
    }
}